package com.wbs.rest.resource;


import com.wbs.rest.config.SqlRestContext;
import com.wbs.rest.handler.SqlModelHandler;
import com.wbs.rest.model.SqlModel;
import com.wbs.rest.model.SqlModelEnum;
import com.wbs.rest.model.SqlModelResolver;
import com.wbs.rest.util.IOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.util.UrlPathHelper;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlResourceInformationHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    Logger log = LoggerFactory.getLogger(SqlResourceInformationHandlerMethodArgumentResolver.class);

    private static final UrlPathHelper URL_PATH_HELPER = new UrlPathHelper();

    SqlRestContext sqlRestContext;

    public SqlResourceInformationHandlerMethodArgumentResolver(SqlRestContext sqlRestContext) {
        this.sqlRestContext = sqlRestContext;
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return SqlResourceInformation.class.isAssignableFrom(methodParameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {

        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        String uri = URL_PATH_HELPER.getLookupPathForRequest(request);

        String content = IOUtil.readFromInputStream(request.getInputStream(), StandardCharsets.UTF_8);
        Map requestMap = requestToMap(request);

        SqlModelResolver sqlModelResolver = sqlRestContext.getSqlModelResolver();

        List<Map> parameterList = sqlModelResolver.resolveParameter(content, requestMap);
        SqlModelEnum modelEnum = sqlModelResolver.resolveSqlModelEnum(parameterList, request.getMethod());
        SqlModel sqlModel = sqlModelResolver.resolveModel(uri, parameterList, modelEnum);


        if(sqlModel == null || sqlModel.getId() == null){
            throw new Exception("no match sql model");
        }

        handleSqlModel(sqlModel, modelEnum);

        return new SqlResourceInformation(sqlModel, sqlRestContext, modelEnum);
    }


    public void handleSqlModel(SqlModel sqlModel, SqlModelEnum modelEnum){
        for(SqlModelHandler handler : sqlRestContext.getSqlModelHandlerList()){
            handler.handle(sqlModel, modelEnum);
        }
    }

    private Map requestToMap(HttpServletRequest request){
        Map data = new HashMap();

        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String parameterName = parameterNames.nextElement();
            data.put(parameterName, request.getParameter(parameterName));
        }

        return data;
    }




}
